package com.iwdnb.gkgz.application.kline;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.google.common.collect.Lists;
import com.iwdnb.gkgz.common.model.dto.StockDayData;
import com.iwdnb.gkgz.common.utils.BigDecimalUtils;
import org.springframework.stereotype.Component;

/**
 * 锤子线
 */
@Component
public class Hammer implements Shape {

    @Override
    public List<StockDayData> getMatchData(String code, List<StockDayData> list,
        List<String> matchDateList) {
        List<StockDayData> stockDayDataList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            StockDayData stockDayData = list.get(i);
            if (!match(code, stockDayData, Lists.newArrayList(list.subList(0, i)))) {
                continue;
            }
            //当日最低价比前面10天最低价还低3个点以上，可以认为锤子线成立
            BigDecimal beforeMinPrice = getBeforeMinPrice(list, i);
            beforeMinPrice = BigDecimalUtils.multiply(beforeMinPrice, new BigDecimal(0.97));
            if (BigDecimalUtils.isLe(stockDayData.getMinPrice(), beforeMinPrice)) {
                stockDayDataList.add(stockDayData);
            }
        }
        return stockDayDataList;
    }

    private BigDecimal getBeforeMinPrice(List<StockDayData> list, int i) {
        List<StockDayData> subList = null;
        if (i < 10) {
            subList = list.subList(0, i);
        } else {
            subList = list.subList(i - 10, i);
        }
        BigDecimal minPrice = new BigDecimal(1000000);
        for (StockDayData stockDayData : subList) {
            if (stockDayData.getMinPrice().compareTo(minPrice) < 0) {
                minPrice = stockDayData.getMinPrice();
            }
        }
        return minPrice;
    }

    @Override
    public boolean match(String code, StockDayData data, List<StockDayData> beforeDatas) {
        if (data.getClosePrice().compareTo(data.getMinPrice()) == 0) {
            return false;
        }

        BigDecimal entityRange = data.getOpenPrice().subtract(data.getClosePrice()).abs();
        if (entityRange.compareTo(BigDecimal.ZERO) == 0) {
            entityRange = BIGDECIMAL_ONE_PERCENT;
        }
        BigDecimal downPrice = data.getOpenPrice().compareTo(data.getClosePrice()) > 0 ? data.getClosePrice()
            : data.getOpenPrice();

        BigDecimal downLineRange = downPrice.subtract(data.getMinPrice());
        if (downLineRange.compareTo(BigDecimal.ZERO) == 0) {
            downLineRange = BIGDECIMAL_ONE_PERCENT;
        }
        BigDecimal downlineEntityRate = downLineRange.divide(entityRange, 1, BigDecimal.ROUND_HALF_UP);
        BigDecimal downlineRate = BigDecimalUtils.divideToPrecent(downLineRange, data.getOpenPrice());
        BigDecimal upPrice = data.getOpenPrice().compareTo(data.getClosePrice()) > 0 ? data.getOpenPrice()
            : data.getClosePrice();
        BigDecimal upLineRange = data.getMaxPrice().subtract(upPrice);
        //下影线长度3个点以上
        if (BigDecimalUtils.isGe(downlineRate, new BigDecimal(3))) {
            return true;
        }
        //振幅=k线主体高价到下影线的低价
        BigDecimal amplitudeRange = upPrice.subtract(data.getMinPrice());
        BigDecimal amplitudeRate = BigDecimalUtils.divideToPrecent(amplitudeRange, data.getOpenPrice());
        //振幅3个点以内,要求下影线和实体比例在两倍以上
        if (BigDecimalUtils.isLe(amplitudeRate, new BigDecimal(3))) {
            //下影线和实体比例在两倍以内,不构成锤子线
            if (BigDecimalUtils.isLt(downlineEntityRate, new BigDecimal("2"))) {
                return false;
            }
        } else {
            //振幅3个点以上,要求下影线占振幅的35%以上
            BigDecimal tempRate = amplitudeRate.multiply(new BigDecimal(0.35));
            //占比不到35%,不构成锤子线
            if (BigDecimalUtils.isLt(downlineRate, tempRate)) {
                return false;
            }
        }

        if (upLineRange.compareTo(BigDecimal.ZERO) == 0) {
            upLineRange = BIGDECIMAL_ONE_PERCENT;
        }
        BigDecimal upRate = BigDecimalUtils.divideToPrecent(upLineRange, data.getOpenPrice());
        //上影线比下影线要短
        if (BigDecimalUtils.isGt(upRate, downlineRate)) {
            return false;
        }
        return true;
    }

    public static void main(String[] args) {
        String code = "sh600021";
        double[] array = new double[] {0.72, 0.75, 0.67, 0.75};
        array = new double[] {0.58, 0.55, 0.53, 0.59};
        array = new double[] {0.5, 0.5, 0.48, 0.52};
        array = new double[] {2.73, 2.78, 2.68, 2.83};
        array = new double[] {0.64, 0.63, 0.6, 0.69};
        array = new double[] {7.35, 7.14, 6.65, 7.38};
        array = new double[] {6.83, 6.95, 6.7, 6.97};
        array = new double[] {7.7, 7.72, 7.58, 7.83};
        StockDayData data = new StockDayData();
        data.setOpenPrice(new BigDecimal(array[0]));
        data.setClosePrice(new BigDecimal(array[1]));
        data.setMinPrice(new BigDecimal(array[2]));
        data.setMaxPrice(new BigDecimal(array[3]));
        Hammer hammer = new Hammer();
        System.out.println(hammer.match(code, data, null));

    }
}
